package com.levi;

import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * @author shentong
 * @date 2021/7/5 20:57
 * @Description TODO
 */
public class HolidayRequest {
    public static void main(String[] args) {
        //1、创建ProcessEngineConfiguration实例,该实例可以配置与调整流程引擎的设置
        ProcessEngineConfiguration cfg=new StandaloneProcessEngineConfiguration()
                //2、通常采用xml配置文件创建ProcessEngineConfiguration，这里直接采用代码的方式
                //3、配置数据库相关参数
                .setJdbcUrl("jdbc:mysql://124.71.29.162:3306/flowable_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b8&nullCatalogMeansCurrent=true")
                .setJdbcUsername("root")
                .setJdbcPassword("St1282001316*")
                .setJdbcDriver("com.mysql.cj.jdbc.Driver")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        //4、初始化ProcessEngine流程引擎实例,创建flowable的一些表
        ProcessEngine processEngine=cfg.buildProcessEngine();

        //创建RepositoryService实例
        RepositoryService repositoryService=processEngine.getRepositoryService();
        //加载流程
        Deployment deployment=repositoryService.createDeployment()
                .addClasspathResource("holiday-request.bpmn20.xml")
                .deploy();

        //查询流程定义
        ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
        System.out.println("Found process definition : "+processDefinition.getName());

        //1、获取流程初始化变量
        Scanner scanner = new Scanner(System.in);

        System.out.println("Who are you?");
        String employee = scanner.nextLine();

        System.out.println("How many holidays do you want to request?");
        Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());

        System.out.println("Why do you need them?");
        String description = scanner.nextLine();

        //2、使用RuntimeService启动一个流程实例,把创建的任务插入到数据库中
        RuntimeService runtimeService=processEngine.getRuntimeService();
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("employee", employee);
        variables.put("nrOfHolidays", nrOfHolidays);
        variables.put("description", description);
        ProcessInstance processInstance=runtimeService.startProcessInstanceByKey("holiday-request",variables);

        //通过TaskService查询 分配给 manager 组的任务
        TaskService taskService=processEngine.getTaskService();
        List<Task> tasks=taskService.createTaskQuery().taskCandidateGroup("managers").list();
        System.out.println("You have " + tasks.size() + " tasks:");
        for (int i=0; i<tasks.size(); i++) {
            System.out.println((i+1) + ") " + tasks.get(i).getName());
        }

        //使用集合下标获取特定流程实例的变量,在控制台输出
        System.out.println("Which task would you like to complete?");
        int taskIndex = Integer.parseInt(scanner.nextLine());
        Task task=tasks.get(taskIndex-1);
        //根据任务id获取传入的变量 map
        Map<String,Object> processVariables=taskService.getVariables(task.getId());
        System.out.println(processVariables.get("employee") + " wants " +
                processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?");


        //经理完成任务
        boolean approved=scanner.nextLine().toLowerCase().equals("y");
        variables = new HashMap<String, Object>();
        variables.put("approved", approved);
        //任务完成，并会在离开排他网关的两条路径中，基于’approved ’流程变量选择一条
        taskService.complete(task.getId(),variables);

        /**
         * 根据传入的条件参数  查询历史任务
         */
        HistoryService historyService = processEngine.getHistoryService();
        List<HistoricActivityInstance> histtoryList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstance.getId())  //流程实例的id
                .finished() //已完成
                .orderByHistoricActivityInstanceEndTime()//流程实例结束时间
                .asc() //排序
                .list();//返回list集合
        for (HistoricActivityInstance activity : histtoryList) {
            System.out.println(activity.getId() + "took" + activity.getDurationInMillis() + "milliseconds!");
        }
    }
}
